<?
/* / / / / / ENGINE  CORE / / / / / / /
|	          CORE CLASS              |
|       (aka. CMS superclass)         |
|                                     |
| version:     0.2.0                  |
| last edit:   20100131               |
| package:     beta 2                 |
/ / / / / / / / / / / / / / / / / / /*/


class ENGINE__backend extends ENGINE {
	function __construct() {
		global $Request;
		
		// LOAD USER DATA
		$this->user_session( 1 );
		
		// LOAD POST DATA
		$this->request = $Request = $this->check_postset();
		
		
		// BUILDING IMPLEMENTED CLASSES
		$this->text = new CORE_TEXT();
		$this->testuser = new ENGINE_USER(); //!!!
		$this->object = new CORE_OBJECT();
	}

/** 	USER FUNCS
* User conditionals, data get/push and session control
* Should be in extended class in the future */
	function user ( $what = "ID" ) {
		
		return ( $var = $this->uservars[ $what ] )? $var : $this->user_extend( $what );
	}

	function user_extend( $what ) {
		global $DB;
		
		return ( $meta = $this->uservars[ "meta" ]->{ $what })? $meta : false;
	}

	function user_session( $private = 0 ) {
		
		global $DB;
		if( isset( $_SESSION['uid'] ) ){
			$this->uservars = $DB->get( "user", "ID=" . $DB->smartq( $_SESSION['uid'], "int" ) . (( $private )?
				" && (ip='".gethostbyname( $_SERVER['REMOTE_ADDR'] )."' || multiple=1) && date_add(llog,interval timer minute) > now()" : "") );
		
			$this->uservars[ "meta" ] = json_decode(( $meta = $this->uservars[ "meta" ])? $meta : "{}"); 
		
		} else unset( $this->uservars );
		
		if( $private ) return $this->user_session_private();
		else return ( $this->uservars );
	}

	function user_session_private() {
		
		global $DB;
		if( $this->user() && $this->user( 'rank' ) > 5 ) {
		
			$DB->query( "UPDATE user SET llog=NOW() WHERE ID='". $this->user() ."'", 0 );
			return true;
			
		} else {
			return false;
		}
	}
	
	function user_authenticate( $user, $password, $rank = 7 ) {
		
		global $DB;
		if( $this->uservars = $DB->get( 'user', "user=". $DB->smartq( $user ) ." AND rank>=$rank AND pass=". $DB->smartq( $password ) )) {
			
			$_SESSION['uid'] = $this->uservars[ 'ID' ];
			$DB->query( "UPDATE user SET ip='".gethostbyname($_SERVER['REMOTE_ADDR'])."', llog=NOW() WHERE ID=". $this->user( "ID" ) );
			$DB->query( "UPDATE mod_user SET tlog=tlog+1 WHERE ID=". $this->user( "ID" ) );
				return true;
		} else	return false;
	}
	
	private function check_postset () {

		if( $_POST['set'] ) return new CORE_REQUEST( json_decode( $_POST['set'])); //Stripslashes removed.
		else return (object) array();
	}

}


/** 	TEXT FUNCS
* Get/set text and conditionals
* 											 */

	class CORE_TEXT {
		function __construct() {
			
		}
		
		public function filter( $textid, $column = "short" ) {
			global $DB;
			
			$response = $DB->query( "select distinct lang, `$column` from txtdump where textid=$textid && active" );
			if( $response )
				while( $row = mysql_fetch_array( $response, MYSQL_ASSOC)) $result[ $row[ 'lang' ]] = $row[ $column ];
		
			return $result;
		}
		
		
		public function get( $textid, $column = "short", $lang = LANG, $strict = false ) {
			global $DB;
			
			 $select = ( $strict || engine_get('lang.master') == $lang ) ?
				 "='$lang'" : "IN('$lang','". engine_get('lang.master') ."') ORDER BY lang ".(($lang > engine_get('lang.master'))? "DESC":"");
		
			return $DB->query_direct( "select `$column` from txtdump where textid = $textid && lang $select limit 1" );
		}
		
		public function set( $text, $textid = 0, $column = "short", $lang = LANG ) {
			global $DB;
			if( $textid && $DB->query_direct( "select textid from txtdump where textid=$textid && lang='$lang'" ))
				$DB->query( "update txtdump set `$column` = ".$DB->smartq( utf8_decode( $text ))." where textid=$textid && lang='$lang'", 0 );
			
			else {
				if( !$textid ) $textid = $this->maxid() + 1;
				$DB->query( "insert into txtdump( textid, lang, `$column`, active, llog, author ) values ( $textid, '$lang', ".$DB->smartq( utf8_decode( $text )).", 1, now(), '".$_SESSION['uid']."')", 0 );
			}
			return $textid;
		}

				
		public function reference( $objtype, $objid, $column = "short", $objcolumn = "nameid" ) {
			global $DB;
			
			if( $objcolumn == "nameid" && $column == "long" ) $objcolumn = "textid";
			
			return $DB->get_key( $objtype, "ID = $objid", "<%lang:$objcolumn:$column%>" );
		}
		
		
		public function search( $string, $column = "short", $lang = LANG ) {
			global $DB;
			
			if( $response = $DB->query( "select textid, `$column` from txtdump where `$column` like ".$DB->smartq( "%". $string ."%" )." && lang='$lang'" ));
				while( $row[] = mysql_fetch_array( $response, MYSQL_ASSOC));
		
			return $row;
		}
		
		
		public function maxid() {
			global $DB;
			
			return (int) $DB->query_direct( "select MAX(textid) from txtdump" );
		}
	
	}
	

/** 	OBJECT FUNCS
* Get/set object conditionals and relations
* Should be in extended class in the future */

class CORE_OBJECT {
		function __construct() {
			
		}
		
		public function filter( $type, $condt ) {
			
			global $DB;
			return $DB->filter( $type, $condt );
		}
		
		public function parse_json_list( $type, $condt ) {
			
			global $DB;
			return $DB->filter( $type, $condt );
		}

	
	}


/** 	MODULE FUNCS
* Get/set module variables
* Should be in extended class in the future */



/** 	REFERENCE FUNCS
* Get/set object relations
* Should be in extended class in the future */




/** 	LIST FUNCS
* Get/set groups and lists
* Should be in extended class in the future */


/** 	REQUEST FUNCS
* Set ajax request set and functions
* 											 */

	class CORE_REQUEST extends ENGINE {
		function __construct( $set ) {
		
			$this->_addvars( $set );
		}
		
	
		function parse_list( $column = "ID, rank, ID as key_0, <%lang:nameid%> as key_1, active as key_2", $float = false ) {
			global $DB;
			

			$flow = $this->flow();

			if( $this->vars->flow->order ) foreach( $this->vars->flow->order as $key=>$val ) $order[]= "$key $val";
			else $order[] = "ID desc";
			
			$condt = implode(" && ", $this->flowreqs) ." order by ". implode(',', $order ) ." limit ". $this->vars->flow->current .", ". $this->vars->flow->limit;
			$column = is_array( $column )? implode( ",", array_merge( $column, array("ID") )) : $column . ", ID";
			
			
			if( $nodes = $DB->filter_key( $this->vars->type, $condt, $column )) {
			
				foreach( $nodes as $k=>$obj ) {
					$nodes[ $k ] = $float ?
						array( "id"=>$obj['ID'], "type"=>$this->vars->type, "rank"=> ( $r = $obj['rank'] )? $r: 0, "name"=> $obj['ID'], "list"=> array( $obj["key_0"], $obj[ "key_1" ])) :
						array( "id"=>$obj['ID'], "type"=>$this->vars->type, "rank"=> ( $r = $obj['rank'] )? $r: 0, "list"=> array( $obj["key_0"], strlimit( $obj["key_1"], 42), $obj[ "key_2" ]));
				}
			}

			return $float ?
				json_encode(( $nodes)? $nodes : array()) : 
				json_encode(( $nodes)? $nodes : array()) . ", $flow, " . json_encode( $this->vars->reqs );
		}
	
		function flow() {
			global $DB;
		
			if( !$flow = $this->vars->flow) $flow = (object) array();
			if( $this->vars->reqs ) foreach( $this->vars->reqs as $key=>$val ) $this->flowreqs[] = "$key='$val'";
			if( !$this->flowreqs ) $this->flowreqs[] = "ID>0";
		
			$flow->total = (int) $DB->get_key( $this->vars->type, implode(" && ", $this->flowreqs), "count(*)" );
	
			if( $this->direction == "prev" )
				$flow->current = ( !$flow->current && $flow->limit < $flow->total )? $flow->total - $flow->limit : (( $flow->limit > $flow->current )? 0: $flow->current - $flow->limit );
			else if( $this->direction == "next" )
				$flow->current = ( $flow->current < $flow->total - $flow->limit)? $flow->current + $flow->limit : 0;
			else if( !$flow->current ) $flow->current = 0;

			return json_encode( $this->vars->flow = $flow ); 
		}

		
		function ajax() {
			global $DB;
			
#			Check if refential value
			if( $this->vars->ref )
				return $this->ajax_ref();
				
#			Else proceed normal.
			if( $this->vars->value )
				$this->vars->key = $this->vars->value;
		
			$value = ($this->vars->options)?
				$this->vars->options[ (int)$this->vars->key ] : $this->vars->key;

			if( strpos( $this->vars->field, "." ))
				$value = $this->update_json( $this->vars->field, $value, $this->vars->objid );
			
			$DB->query( "UPDATE " . (( $this->vars->type == "module" )? "moddump" : $DB->type( $this->vars->type, "table" )) . " SET ".$this->vars->field."='$value' WHERE ID=".(( $id = $this->vars->objid )? $id : $id = $this->vars->id ));
			
			return $id;
		}
		
		function ajax_ref() {
			global $DB;
			
			$id		= (int) $this->vars->key;
			$ref	= $this->vars->ref;
			
			if( $DB->reference( $ref->parenttype, (int) $ref->parentid, $ref->objtype, (int) $ref->objid ))
				$DB->query( "delete from glue_object where parenttype = {$DB->type( $ref->parenttype )} && objtype = {$DB->type( $ref->objtype )} && parentid = {$ref->parentid} && objid = {$ref->objid}");
			else if( $ref->single )
				$DB->query( "delete from glue_object where parenttype = {$DB->type( $ref->parenttype )} && objtype = {$DB->type( $ref->objtype )} && ". ( $ref->master? "parentid = {$ref->parentid}" : "objid = {$ref->objid}" ));
			
			return (int) $DB->set_reference ( $ref->parenttype, (int) $ref->master? $ref->parentid : $id, $ref->objtype, (int) $ref->master? $id : $ref->objid );

		}

		
		function referential() {
			global $DB;
			
			$condt = array( "active" );
			
			if( $rel = $this->vars->relation )
				if( $relations = $DB->reference( $rel->parenttype, (int) $rel->parentid, ( $objtype = $this->vars->objtype )? $objtype : $this->vars->ref->parenttype ))
					$condt[] = "ID in( " . implode( ",", $relations ) . ")";


			if(  $ref = $this->vars->ref )
				 $objtype = $ref->master? $ref->objtype: $ref->parenttype;
			
			$options = $DB->filter_key( $objtype, implode( " && ", $condt ) . " order by rank desc, value limit 20", "ID as `key`, <%lang:nameid%> as value" );	
			
			
			return '{ "opts": '. json_encode( $options ) .' }';
			
			/*{"transfer_type":"js","type":"cal.single","action":"referential","vars":{
				"type":"cal.single","descr":"bestemming","objid":218,"field":"objid","objtype":"bestemming","key":"31","value":"Kappl - Ischgl","relation":{
					"parenttype":"country","objtype":"cal.single","parentid":40,"objid":218,"master":0,"single":1
				}}}*/
			
			
			/*if( $objs = $DB->filter_objects( $this->vars->ref->{( $this->vars->ref->master )? "objtype":"parenttype" }, implode( " && ", $condt )))
				foreach( $objs as $obj )
					$result[ 'opts' ][ $obj->get('name') ] = $obj->id;

			if( !$this->vars->value && $this->vars->ref && $value = ( $this->vars->ref->master )? $DB->reference( $this->vars->ref->parenttype, (int) $this->vars->objid, $this->vars->ref->objtype ) : $DB->reference_by_child( $this->vars->ref->parenttype, $this->vars->ref->objtype, (int) $this->vars->objid ))
				$result[ 'value' ] = array_shift( $value );

			return json_encode( $result? $result : (object) array());*/
		}
		
		function update_json( $string, $value, $id, $return_string = 1 ) {
			global $DB;
			
			$field = explode( ".", $string );
			$this->vars->field = array_shift( $field );

			$json = json_decode(( $jsonraw = ( $this->vars->type == "module" )?
				$DB->query_direct( "select json from moddump where ID={$id}" ) : $DB->get_key( $this->vars->type, "ID={$id}", $this->vars->field ))? $jsonraw : "{}" );
				
			foreach( $field as $n => $fld )
				if( $n == count( $field )-1) if( !$digger ) $json->{ $fld } = $value; else $digger->{ $fld } = $value;
				else if( $digger ) $digger = &$digger->{ $fld };
				else $digger = &$json->{ $fld };

			
			return ( $return_string )? json_encode( $json ) : $json;
		}

	
	}


?>